home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’92 / Notification Stuff ƒ / GestaltTalk / GestaltTalkCommands.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-19  |  5.6 KB  |  305 lines  |  [TEXT/KAHL]

  1. /*
  2.     GestaltTalkCommands
  3.     -------------------
  4.  
  5.     By Brigham Stevens
  6.     Apple Computer DTS
  7. */
  8.  
  9.  
  10. #include <GestaltTalk.h>
  11.  
  12. /*    initialize everything - call first */
  13. static OSErr GestaltTalkInit(GestaltTalkPB *gpb);
  14.  
  15. /* returns the number of bytes in buffer */
  16. static OSErr GestaltTalkStatus(GestaltTalkPB *gpb);
  17.  
  18. /* read some bytes from the buffer */
  19. static OSErr GestaltTalkRead(GestaltTalkPB *gpb);
  20.  
  21. /* write some bytes to the buffer */
  22. static OSErr GestaltTalkWrite(GestaltTalkPB *gpb);
  23.  
  24. /* If an application registers, then an init can wake it up at the 'right times' */
  25. static OSErr GestaltTalkRegister(GestaltTalkPB *gpb);
  26.  
  27. /* call before your app quits so the init will not try to wake you */
  28. static OSErr GestaltTalkUnregister(GestaltTalkPB *gpb);
  29.  
  30. /* Used to get the PSN of the registerd application (pointer to it in data) */
  31. static OSErr GestaltTalkGetRegisteredApp(GestaltTalkPB *gpb);
  32.  
  33. /* This function gets the address of the gestalt talk buffer and stores 
  34.     the returned pointer in gtData 
  35.     Then future GestaltTalk calls will be faster becuase they will not
  36.     use Gestalt to get the address of the buffer */
  37. static OSErr GestaltTalkUserInit(GestaltTalkPB *gpb);
  38. /*
  39.     This function gets the address of the gestalt talk buffer
  40. */
  41. static OSErr GetGestaltTalkBuffer(gtp *g);
  42.  
  43. #ifdef BUILD_INIT
  44.     pascal OSErr GestaltTalkGestalt(long selector, long *response);
  45. #endif
  46.  
  47.  
  48. /*
  49.     This is the main entry point to GestaltTalk
  50.     All of the other routines should be access by filling
  51.     out the gestaltTalk parameter block and calling this
  52. */
  53. OSErr GestaltTalk(GestaltTalkPB *gpb)
  54. {
  55.     OSErr    err = 0;
  56.     
  57.     switch(gpb->command) {
  58. #ifdef BUILD_INIT
  59.         case ginit:            err = GestaltTalkInit(gpb);
  60.                             break;
  61. #endif
  62.         case gstatus:        err = GestaltTalkStatus(gpb);
  63.                             break;
  64.         case gread:            err = GestaltTalkRead(gpb);
  65.                             break;
  66.         case gwrite:        err = GestaltTalkWrite(gpb);
  67.                             break;
  68.         case gregister:        err = GestaltTalkRegister(gpb);
  69.                             break;
  70.         case gunregister:    err = GestaltTalkUnregister(gpb);
  71.                             break;
  72.         case ggetapp:        err = GestaltTalkGetRegisteredApp(gpb);
  73.                             break;
  74.         case guserinit:        err = GestaltTalkUserInit(gpb);
  75.                             break;
  76.         default:            return paramErr;
  77.     }
  78.     
  79.     return err;
  80. }
  81.  
  82.  
  83.  
  84. #ifdef BUILD_INIT
  85.  
  86. static OSErr GestaltTalkInit(GestaltTalkPB *gpb)
  87. {
  88.     gtp        g;
  89.     OSErr    err = 0;
  90.     
  91.  
  92.     err = GetGestaltTalkBuffer(&g);
  93.     if(err)    {
  94.         DebugStr("\p GestaltTalkInit - GetGestaltTalkBuffer failed.");
  95.         goto bail;
  96.     }
  97.     g->dataBuffer = NewPtrSysClear(bufferSize);
  98.  
  99.     if(!g->dataBuffer) {
  100.         err = MemError();
  101.         DebugStr("\p GestaltTalkInit - NewPtrSysClear failed.");
  102.         goto bail;
  103.     }
  104.     
  105.     g->buffCount = 0;
  106.  
  107. bail:
  108.     return err;
  109. }
  110. #endif
  111.  
  112. /*
  113.     gets the number of bytes in the buffer in datalength
  114. */
  115. OSErr GestaltTalkStatus(GestaltTalkPB *gpb)
  116. {
  117.     short     err = 0;    
  118.     gtp        g;
  119.     
  120.     if(gpb->gtData)
  121.         g = gpb->gtData;
  122.     else {
  123.         err = GetGestaltTalkBuffer(&g);
  124.         if(err)    goto bail;
  125.     }
  126.     
  127.     gpb->datalength = g->buffCount;
  128.  
  129. bail:    
  130.     return err;
  131. }
  132.  
  133.  
  134. OSErr GestaltTalkRead(GestaltTalkPB *gpb)
  135. {
  136.     short     err = 0;
  137.     gtp        g;
  138.     
  139.     if(gpb->gtData)
  140.         g = gpb->gtData;
  141.     else {
  142.         err = GetGestaltTalkBuffer(&g);
  143.         if(err)    goto bail;
  144.     }
  145.     
  146.     if(!g->buffCount) {
  147.         gpb->datalength = 0;
  148.         goto bail;
  149.     }
  150.  
  151.     if(gpb->datalength < g->buffCount) {
  152.         err = readErr;
  153.         BlockMove(g->dataBuffer, gpb->data, gpb->datalength);
  154.     } else if (gpb->datalength > g->buffCount)
  155.         err = eofErr;
  156.  
  157.     BlockMove(g->dataBuffer, gpb->data, g->buffCount);
  158.     gpb->datalength = g->buffCount;
  159.  
  160. /*        right now this only supports one entry */
  161. /*        next version supports multiple entries */
  162.     g->buffCount = 0;
  163.  
  164. bail:    
  165.     return err;
  166. }
  167.  
  168.  
  169.  
  170. OSErr GestaltTalkWrite(GestaltTalkPB *gpb)
  171. {
  172.     short     err = 0;
  173.     gtp        g;
  174.     
  175.     if(gpb->gtData)
  176.         g = gpb->gtData;
  177.     else {
  178.         err = GetGestaltTalkBuffer(&g);
  179.         if(err)    goto bail;
  180.     }
  181.     
  182.     if(!gpb->datalength) {
  183.         err = paramErr;
  184.         goto bail;
  185.     }
  186.     if(gpb->datalength > bufferSize) {
  187.         err = writErr;
  188.         BlockMove(gpb->data,g->dataBuffer,bufferSize);
  189.         g->buffCount = bufferSize;
  190.         gpb->datalength = bufferSize;
  191.     } else {
  192.         BlockMove(gpb->data,g->dataBuffer,gpb->datalength);
  193.         g->buffCount = gpb->datalength;
  194.     }
  195.         
  196. bail:
  197.     return err;
  198. }
  199.  
  200.  
  201.  
  202. /*
  203.     If an appliation registers it's PSN with GestaltTalk
  204.     then the PoliteNotification init will wake up the application
  205.     so it can fetch the notification message from the buffers.
  206. */
  207. /* can be called from an interrtupt */
  208. OSErr GestaltTalkRegister(GestaltTalkPB *gpb)
  209. {
  210.     short    err = 0;
  211.     gtp        g;
  212.     
  213.     if(gpb->gtData)
  214.         g = gpb->gtData;
  215.     else {
  216.         err = GetGestaltTalkBuffer(&g);
  217.         if(err)    goto bail;
  218.     }
  219.     
  220.     g->appPSN = *(ProcessSerialNumber*)gpb->data;
  221.     g->appRegistered = 0x01;
  222.     
  223. bail:
  224.     return err;
  225.  
  226. }
  227.  
  228. /*  can be called from an interrtupt  */
  229. OSErr GestaltTalkUnregister(GestaltTalkPB *gpb)
  230. {
  231.     short                err = 0;
  232.     gtp                    g;
  233.     
  234.     if(gpb->gtData)
  235.         g = gpb->gtData;
  236.     else {
  237.         err = GetGestaltTalkBuffer(&g);
  238.         if(err)    goto bail;
  239.     }
  240.     
  241.     g->appRegistered = false;    
  242.  
  243. bail:    
  244.     return err;
  245.  
  246. }
  247.  
  248. OSErr GestaltTalkGetRegisteredApp(GestaltTalkPB *gpb)
  249. {
  250.     short    err = 0;
  251.     gtp        g;
  252.     
  253.     if(gpb->gtData)
  254.         g = gpb->gtData;
  255.     else {
  256.         err = GetGestaltTalkBuffer(&g);
  257.         if(err)    goto bail;
  258.     }
  259.     
  260.     if(!g->appRegistered) {
  261.         err = paramErr;
  262.         goto bail;
  263.     }
  264.  
  265.     gpb->data = &g->appPSN;
  266.     gpb->datalength = sizeof(ProcessSerialNumber);
  267.     
  268. bail:    
  269.     return err;
  270.  
  271. }
  272.  
  273. /*
  274.     This procedure returns the address of the GTalk buffer
  275. */
  276. static OSErr GestaltTalkUserInit(GestaltTalkPB *gpb)
  277. {
  278.     short     err = 0;
  279.     gtp        g;
  280.     
  281.     err = GetGestaltTalkBuffer(&g);
  282.     gpb->gtData = g;
  283.         
  284. bail:    
  285.     return err;
  286. }
  287.  
  288. OSErr GetGestaltTalkBuffer(gtp *g)
  289. {
  290.     OSErr    err = 0;
  291.     
  292.     #ifdef BUILD_INIT
  293.         return GestaltTalkGestalt(gestaltTalkSelector, (long*)g);
  294.     #endif
  295.     
  296.     #ifdef BUILD_USER
  297.     asm {
  298.             move.l    #gestaltTalkSelector,d0
  299.             _Gestalt
  300.             move.l    g,a1
  301.             move.l    a0,(a1)
  302.         }
  303.     #endif
  304. }
  305.